import { JSEncrypt } from 'jsencrypt';
import { KEYUTIL, KJUR, b64tohex, hextob64 } from 'jsrsasign';

/**
 * RSA加密
 *
 * @param publicKey 公钥
 * @param plainText 明文
 * @returns {*} 密文
 */
const encryptByRSA = function (publicKey: string, plainText: string): string | false {
  const encryptor = new JSEncrypt();
  encryptor.setPublicKey(publicKey);
  return encryptor.encrypt(plainText);
};

/**
 * RSA解密
 *
 * @param privateKey 私钥
 * @param cipherText 密文
 * @returns {*} 明文
 */
const decryptByRSA = function (privateKey: string, cipherText: string): string | false {
  const decrypter = new JSEncrypt();
  decrypter.setPrivateKey(privateKey);
  return decrypter.decrypt(cipherText);
};

/**
 * 生成RSA密钥对，填充模式为PKCS8。
 * 更多模式参考：
 * <a href="https://kjur.github.io/jsrsasign/api/symbols/KEYUTIL.html">https://kjur.github.io/jsrsasign/api/symbols/KEYUTIL.html</a>
 *
 * @returns {{privateKey: (string|string|*), publicKey: (string|string|*)}}
 */
const generateRsaKeyWithPKCS8 = function (): { privateKey: string; publicKey: string } {
  const keyPair = KEYUTIL.generateKeypair('RSA', 1024);
  const privateKey = KEYUTIL.getPEM(keyPair.prvKeyObj, 'PKCS8PRV');
  const publicKey = KEYUTIL.getPEM(keyPair.pubKeyObj);
  return { privateKey, publicKey };
};

/**
 * SHA256和RSA加签
 *
 * @param privateKey 私钥
 * @param msg 加签内容
 * @returns {string} Base64编码签名内容
 */
const signBySHA256WithRSA = function (privateKey: string, msg: string): string {
  const key = KEYUTIL.getKey(privateKey);
  const signature = new KJUR.crypto.Signature({
    alg: 'SHA256withRSA'
  });
  signature.init(key);
  signature.updateString(msg);
  // 签名后的为16进制字符串，这里转换为16进制字符串
  return hextob64(signature.sign());
};

/**
 * SHA256和RSA验签
 *
 * @param publicKey 公钥：必须为标准pem格式。如果是PKCS1格式，必须包含-----BEGIN RSA PRIVATE KEY-----，如果是PKCS8格式，必须包含-----BEGIN PRIVATE KEY-----
 * @param base64SignStr Base64编码签名字符串
 * @param msg 原内容
 * @returns {boolean} 是否验签通过
 */
const verifyBySHA256WithRSA = function (publicKey: string, base64SignStr: string, msg: string): boolean {
  const key = KEYUTIL.getKey(publicKey);
  const signature = new KJUR.crypto.Signature({
    alg: 'SHA256withRSA'
  });
  signature.init(key);
  signature.updateString(msg);
  // 需要将Base64进制签名字符串转换成16进制字符串
  return signature.verify(b64tohex(base64SignStr));
};

// function test() {
//   const { privateKey, publicKey } = generateRsaKeyWithPKCS8();
//   console.log(`生成的私钥为：\n${privateKey}`);
//   console.log(`生成的公钥为：\n${publicKey}`);

//   const cipherText = encryptByRSA(publicKey, 'password');
//   console.log(`test加密后的内容为：\n${cipherText}`);

//   const plainText = decryptByRSA(privateKey, cipherText as string);
//   console.log(`解密后的内容为：\n${plainText}`);

//   const signature = signBySHA256WithRSA(privateKey, 'password');
//   console.log(`生成的签名：\n${signature}`);

//   const isVerified = verifyBySHA256WithRSA(publicKey, signature, 'password');
//   console.log(`是否验签通过：${isVerified}`);
// }

export { encryptByRSA, decryptByRSA, generateRsaKeyWithPKCS8, signBySHA256WithRSA, verifyBySHA256WithRSA };
